package ac.neec.mio.ui.fragment;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

import ac.neec.data.HeartRate;
import ac.neec.data.RecordDate;
import ac.neec.data.RecordDetail;
import ac.neec.data.SpecificActivities;
import ac.neec.data.User;
import ac.neec.listener.EventsCallBackListener;
import ac.neec.listener.HeartRateEventListener;
import ac.neec.mio.R;
import ac.neec.mio.ui.activity.MeasurementActivity;
import ac.neec.mio.ui.activity.MeasurementResultActivity;
import ac.neec.timewatch.StopWatch;
import ac.neec.timewatch.TimeWatchInterface;
import ac.neec.timewatch.TimeWatchSubject;
import ac.neec.util.CalorieCompute;
import ac.neec.util.HeartRateCompute;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

/**
 * Created by kobayashi on 2014/01/26.
 */
public class MeasurementHeartRateFlagment extends Fragment implements
		HeartRateEventListener<String>, TimeWatchInterface, OnClickListener {
	private static final int HANDLE_ID_HEART_RATE = 0;
	private static final int HANDLE_ID_TIME = 1;
	private static final int HANDLE_ID_CALORIE = 2;
	private static final int HANDLE_ARG_CALORIE_THEORY = 21;
	private static final int HANDLE_ARG_CALORIE_POINT = 22;
	private volatile String time;
	private boolean flag = false;
	private int pointTarget;
	private int theoryTarget;
	private int theoryLevel;
	private int pointLevel;
	private float theoryMETs;
	private float pointMETs;
	private float weight;
	private HeartRate mHeartRates;
	private User user;
	private SpecificActivities specificActivities;
	private TimeWatchSubject restingMeasurementSubject;
	private StopWatch stopWatch;
	private TextView timeView;
	private TextView calorieThory;
	private TextView caloriePoint;
	private TextView heartRateNow;
	private TextView heartRateMax;
	private Button stopButton;
	private EventsCallBackListener<Object> mCallbackListener;
	private Handler mHeartRateHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			heartRateNow.setText((String) msg.obj);
		}
	};
	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case HANDLE_ID_TIME:
				timeView.setText((String) msg.obj);
				time = (String) msg.obj;
				break;
			case HANDLE_ID_CALORIE:
				if (msg.arg1 == HANDLE_ARG_CALORIE_THEORY)
					calorieThory.setText((String) msg.obj);
				else if (msg.arg1 == HANDLE_ARG_CALORIE_POINT)
					caloriePoint.setText((String) msg.obj);
				break;
			default:
				break;
			}
		}
	};

	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		try {
			mCallbackListener = (EventsCallBackListener) activity;
		} catch (ClassCastException e) {
			throw new ClassCastException(activity.toString()
					+ " must implement OnArticleSelectedListener");
		}
	}

	@Override
	public void onCreate(Bundle savedStateInstance) {
		super.onCreate(savedStateInstance);

		Bundle bundle = getArguments();
		theoryLevel = bundle.getInt("theoryLevel");
		pointLevel = bundle.getInt("pointLevel");
		theoryMETs = bundle.getFloat("theoryMETs");
		pointMETs = bundle.getFloat("pointMETs");
		specificActivities = (SpecificActivities) bundle.getSerializable("specificActivities");
		user = (User) bundle.getSerializable("user");

		mHeartRates = new HeartRate();
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedStateInstance) {
		View view = inflater.inflate(R.layout.fragment_measurement, container,
				false);

		linkVIew(view);
		theoryTarget = HeartRateCompute.calcTargetHeartRateKarvonen(user.getAge(), user.getTargetHeartRate(),
				(float) theoryLevel / 100);
		heartRateMax.setText(String.valueOf(theoryTarget));
		pointTarget = HeartRateCompute.calcTargetHeartRateKarvonen(user.getAge(), user.getTargetHeartRate(),
				(float) pointLevel / 100);

		return view;
	}

	private void linkVIew(View view) {
		timeView = (TextView) view.findViewById(R.id.act_measurement_time);
		calorieThory = (TextView) view
				.findViewById(R.id.act_measurement_cal_thory);
		caloriePoint = (TextView) view
				.findViewById(R.id.act_measurement_cal_point);
		heartRateNow = (TextView) view
				.findViewById(R.id.act_measurement_heartrate_now);
		heartRateMax = (TextView) view
				.findViewById(R.id.act_measurement_heartrate_max);
		stopButton = (Button) view
				.findViewById(R.id.act_measurement_heartrate_stop_button);
		stopButton.setOnClickListener(this);
	}

	@Override
	public synchronized void onClick(View v) {
		if (flag == true) {
			stopMeasurement();
		}
		else {
			startMeasurement();
			stopButton.setText("停止");
			flag = true;
		}
	}

	public void startMeasurement() {
		mCallbackListener.onCallBack(MeasurementActivity.CALLBACK_ID_MEASUREMENT_START, null);

		stopWatch = new StopWatch(this);
		stopWatch.addObservers(this);
		stopWatch.startTimer();
	}

	public void stopMeasurement() {
		stopWatch.cancel();
		Intent intent = new Intent(getActivity()
				.getApplicationContext(),
				MeasurementResultActivity.class);
		intent.putExtra("user", user);
		intent.putExtra("detail", setupRecordDetailInstance());
		intent.putExtra("pointMETs", pointMETs);
		intent.putExtra("pointLevel", pointLevel);
		intent.putExtra("theoryLevel", theoryLevel);
		startActivity(intent);
		mCallbackListener.onCallBack(MeasurementActivity.CALLBACK_ID_MEASUREMENT_STOP,
				null);
	}

	@Override
	public void notifyHeartRateEvent(final String value) {
		Log.e("HEART RATE", value);
		mHeartRates.addHeartRate(Integer.valueOf(value));
		mHeartRateHandler.obtainMessage(HANDLE_ID_HEART_RATE, value).sendToTarget();
	}

	@Override
	public void notifyTimerUpdata(long time) {
		mHandler.obtainMessage(HANDLE_ID_TIME, convertTimeString(time))
				.sendToTarget();
		float theory = CalorieCompute.calcCalorie(theoryMETs, time, weight);
		float point = CalorieCompute.calcCalorie(pointMETs, time, weight);
		mHandler.obtainMessage(HANDLE_ID_CALORIE, HANDLE_ARG_CALORIE_POINT, 0, String.valueOf(point)).sendToTarget();
		mHandler.obtainMessage(HANDLE_ID_CALORIE, HANDLE_ARG_CALORIE_THEORY, 0, String.valueOf(theory)).sendToTarget();
	}

	private String convertTimeString(long time) {
		long hour = TimeUnit.HOURS.convert(time, TimeUnit.MILLISECONDS);
		long min = TimeUnit.MINUTES.convert(time, TimeUnit.MILLISECONDS) % 60;
		long sec = TimeUnit.SECONDS.convert(time, TimeUnit.MILLISECONDS) % 60 % 60;
		long msec = time % 1000;
		return String.format("%02d:%02d'%02d''%02d", hour, min, sec, msec);
	}

	private synchronized RecordDetail setupRecordDetailInstance() {
		String s_date = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
		RecordDate date = new RecordDate(s_date);
		RecordDetail detail = new RecordDetail(date, specificActivities,
				time,
				theoryTarget,
				pointTarget,
				Float.valueOf((String) calorieThory.getText()),
				Float.valueOf((String) caloriePoint.getText()),
				mHeartRates.getHeartRatesBytes());

		return detail;
	}

	@Override
	public void onCancel() {
	}

	@Override
	public void onAlarm() {
	}
}
